﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Drawing.Drawing2D;
using System.Reflection;
using System.Windows.Forms;
using HML.Design;

namespace HML
{
    /// <summary>
    /// 页码导航控件
    /// </summary>
    [Description("页码导航控件")]
    [DefaultProperty("StyleText")]
    [DefaultEvent("PaginationChanged")]
    [TypeConverter(typeof(PaginationBarConverter))]
    [Designer(typeof(PaginationBarDesigner))]
    [ToolboxItem(true)]
    [ToolboxBitmap(typeof(PaginationBar), "Controls.PaginationBar.Resources.PaginationBar.bmp")]
    public class PaginationBar : DpiControl, ISkinObject
    {
        #region 主题

        private SkinObjectXmlMetadata skinObjectXmlMetadata = null;
        /// <summary>
        /// 主题对象在主题文件信息
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual SkinObjectXmlMetadata SkinObjectXmlMetadata
        {
            get
            {
                if (this.skinObjectXmlMetadata == null)
                    this.skinObjectXmlMetadata = new SkinObjectXmlMetadata(Assembly.GetAssembly(typeof(PaginationBar)).GetName().Name, typeof(PaginationBar).Name);

                return this.skinObjectXmlMetadata;
            }
        }

        private SkinController skinController = null;
        /// <summary>
        /// 主题控制器
        /// </summary>
        [Description("主题控制器")]
        [Category("杂项")]
        [PropertyOrder(-360)]
        [DefaultValue(null)]
        [RefreshProperties(RefreshProperties.All)]
        public virtual SkinController SkinController
        {
            get { return this.skinController; }
            set
            {
                if (this.skinController == value)
                    return;

                if (this.skinController != null)
                    this.skinController.RemoveSkinObject(this);

                this.skinController = value;

                if (this.skinController != null)
                    this.skinController.AddSkinObject(this);
            }
        }

        private SkinEnabledState skinEnabled= SkinEnabledState.Auto;
        /// <summary>
        /// 主题是否启用
        /// </summary>
        [Description("主题是否启用")]
        [Category("杂项")]
        [PropertyOrder(-300)]
        [DefaultValue(SkinEnabledState.Auto)]
        [RefreshProperties(RefreshProperties.All)]
        public virtual SkinEnabledState SkinEnabled
        {
            get { return this.skinEnabled; }
            set
            {
                if (this.skinEnabled == value)
                    return;

                this.skinEnabled = value;
                this.OnSkinChanged();
            }
        }

        private SkinStyle skinStyle = SkinStyle.Normal;
        /// <summary>
        /// 主题风格
        /// </summary>
        [Description("主题风格")]
        [Category("杂项")]
        [PropertyOrder(-260)]
        [DefaultValue(SkinStyle.Normal)]
        [RefreshProperties(RefreshProperties.All)]
        public virtual SkinStyle SkinStyle
        {
            get { return this.skinStyle; }
            set
            {
                if (this.skinStyle == value)
                    return;

                this.skinStyle = value;
                this.OnSkinChanged();
            }
        }

        private StyleAppearanceObject stateAppearance;
        /// <summary>
        /// 风格外观
        /// </summary>
        [Description("风格外观")]
        [Category("杂项")]
        [PropertyOrder(-200)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public StyleAppearanceObject StyleAppearance
        {
            get
            {
                if (this.stateAppearance == null)
                    this.stateAppearance = new StyleAppearanceObject(this, null);
                return this.stateAppearance;
            }
        }

        /// <summary>
        /// 主题已更改
        /// </summary>
        public virtual void OnSkinChanged()
        {
            SkinManager.SyncSkinValueToProperty(this);
            this.Invalidate();
        }

        private ISkinObject followSkinObject = null;
        /// <summary>
        /// 主题设置跟随指定主题对象（自己的设置不再生效，提供给代码使用）
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [Localizable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual ISkinObject FollowSkinObject
        {
            get { return this.followSkinObject; }
            set
            {
                if (this.followSkinObject == value)
                    return;

                this.followSkinObject = value;
                this.OnSkinChanged();
            }
        }

        public virtual bool GetSkinObjectSkinStateCore()
        {
            return SkinManager.GetSkinObjectSkinState(this.FollowSkinObject ?? this);
        }

        void ISkinObject.InitializeInvalidate()
        {
            this.InitializeElement();
            this.Invalidate();
        }

        void ISkinObject.Invalidate()
        {
            this.Invalidate();
        }

        #endregion

        #region 新增事件

        public delegate void PaginationChangedEventHandler(object sender, PaginationBarChangedEventArgs e);
        private static readonly object EventPaginationChanged = new object();
        /// <summary>
        /// 当前页码更改事件
        /// </summary>
        [Description("当前页码更改事件")]
        public event PaginationChangedEventHandler PaginationChanged
        {
            add { Events.AddHandler(EventPaginationChanged, value); }
            remove { Events.RemoveHandler(EventPaginationChanged, value); }
        }

        #endregion

        #region 停用事件

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler PaddingChanged
        {
            add { base.PaddingChanged += value; }
            remove { base.PaddingChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler TabStopChanged
        {
            add { base.TabStopChanged += value; }
            remove { base.TabStopChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler TextChanged
        {
            add { base.TextChanged += value; }
            remove { base.TextChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler FontChanged
        {
            add { base.FontChanged += value; }
            remove { base.FontChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler RightToLeftChanged
        {
            add { base.RightToLeftChanged += value; }
            remove { base.RightToLeftChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler ImeModeChanged
        {
            add { base.ImeModeChanged += value; }
            remove { base.ImeModeChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler BackgroundImageChanged
        {
            add { base.BackgroundImageChanged += value; }
            remove { base.BackgroundImageChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler BackgroundImageLayoutChanged
        {
            add { base.BackgroundImageLayoutChanged += value; }
            remove { base.BackgroundImageLayoutChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler BackColorChanged
        {
            add { base.BackColorChanged += value; }
            remove { base.BackColorChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler ForeColorChanged
        {
            add { base.ForeColorChanged += value; }
            remove { base.ForeColorChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler Click
        {
            add { base.Click += value; }
            remove { base.Click -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler DoubleClick
        {
            add { base.DoubleClick += value; }
            remove { base.DoubleClick -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event MouseEventHandler MouseClick
        {
            add { base.MouseClick += value; }
            remove { base.MouseClick -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event MouseEventHandler MouseDoubleClick
        {
            add { base.MouseDoubleClick += value; }
            remove { base.MouseDoubleClick -= value; }
        }

        #endregion

        #region 新增属性

        private Padding contentPadding = new Padding(5, 2, 5, 2);
        /// <summary>
        /// 内容区内边距
        /// </summary>
        [Description("内容区内边距")]
        [Category("杂项")]
        [PropertyOrder(-196)]
        [DefaultValue(typeof(Padding), "5, 2, 5, 2")]
        public Padding ContentPadding
        {
            get { return this.contentPadding; }
            set
            {
                if (this.contentPadding == value)
                    return;

                this.contentPadding = value;
                this.InitializeElement();
                this.Invalidate();
            }
        }

        private bool fLButtonVisible = true;
        /// <summary>
        /// 是否显示首页尾页按钮
        /// </summary>
        [Description("是否显示首页尾页按钮")]
        [PropertyOrder(-192)]
        [DefaultValue(true)]
        public bool FLButtonVisible
        {
            get { return this.fLButtonVisible; }
            set
            {
                if (this.fLButtonVisible == value)
                    return;

                this.fLButtonVisible = value;
                this.InitializeElement();
                this.Invalidate();
            }
        }

        private bool pNButtonVisible = true;
        /// <summary>
        /// 是否显示上一页下一页按钮
        /// </summary>
        [Description("是否显示上一页下一页按钮")]
        [PropertyOrder(-190)]
        [DefaultValue(true)]
        public bool PNButtonVisible
        {
            get { return this.pNButtonVisible; }
            set
            {
                if (this.pNButtonVisible == value)
                    return;

                this.pNButtonVisible = value;
                this.InitializeElement();
                this.Invalidate();
            }
        }

        private bool gButtonVisible = true;
        /// <summary>
        /// 是否显示上一组下一组按钮
        /// </summary>
        [Description("是否显示上一组下一组按钮")]
        [PropertyOrder(-188)]
        [DefaultValue(true)]
        public bool GButtonVisible
        {
            get { return this.gButtonVisible; }
            set
            {
                if (this.gButtonVisible == value)
                    return;

                this.gButtonVisible = value;
                this.InitializeElement();
                this.Invalidate();
            }
        }

        private bool recordDescriptionVisible = true;
        /// <summary>
        /// 是否显示记录数描述
        /// </summary>
        [Description("是否显示记录数描述")]
        [PropertyOrder(-187)]
        [DefaultValue(true)]
        public bool RecordDescriptionVisible
        {
            get { return this.recordDescriptionVisible; }
            set
            {
                if (this.recordDescriptionVisible == value)
                    return;

                this.recordDescriptionVisible = value;
                this.InitializeElement();
                this.Invalidate();
            }
        }

        private bool pageDescriptionVisible = true;
        /// <summary>
        /// 是否显示页数描述
        /// </summary>
        [Description("是否显示页数描述")]
        [PropertyOrder(-186)]
        [DefaultValue(true)]
        public bool PageDescriptionVisible
        {
            get { return this.pageDescriptionVisible; }
            set
            {
                if (this.pageDescriptionVisible == value)
                    return;

                this.pageDescriptionVisible = value;
                this.InitializeElement();
                this.Invalidate();
            }
        }

        private string template = "当前共有[*]条|首页|上一页|...|...|下一页|尾页|共[*]页";
        /// <summary>
        /// 显示风格模板（有7个|分隔开来，[*]代表记录总数量。格式错误则采用默认配置）
        ///  例子：“当前共有[*]条|首页|上一页|...|...|下一页|尾页|共[*]页”
        /// </summary>
        [Description("显示风格模板")]
        [Category("杂项")]
        [PropertyOrder(-182)]
        [DefaultValue("当前共有[*]条|首页|上一页|...|...|下一页|尾页|共[*]页")]
        public string Template
        {
            get { return this.template; }
            set
            {
                if (this.template == value)
                    return;

                this.template = value;
                this.InitializeElement();
                this.Invalidate();
            }
        }

        private int limitPage = 7;
        /// <summary>
        /// 导航一次最多显示多少个页码（建议为奇数，最小值为5）
        /// </summary>
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public int LimitPage
        {
            get { return this.limitPage; }
        }

        private int totalRecords = 0;
        /// <summary>
        /// 总记录数
        /// </summary>
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public int TotalRecords
        {
            get { return this.totalRecords; }
        }

        private int pageSize = 0;
        /// <summary>
        /// 多少条记录为一页
        /// </summary>
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public int PageSize
        {
            get { return this.pageSize; }
        }

        private int totalPages = 0;
        /// <summary>
        /// 总页数
        /// </summary>
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public int TotalPages
        {
            get { return this.totalPages; }
        }

        private int currentPage = 0;
        /// <summary>
        /// 当前页码(1开始)
        /// </summary>
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public int CurrentPage
        {
            get { return this.currentPage; }
        }

        /// <summary>
        /// 首页按钮鼠标是否已进入
        /// </summary>
        [Browsable(false)]
        public bool FirstButtonIsMouseEnter
        {
            get { return this.mouseenterobject == this.body.first_button; }
        }

        /// <summary>
        /// 上一页按钮鼠标是否已进入
        /// </summary>
        [Browsable(false)]
        public bool PrevButtonIsMouseEnter
        {
            get { return this.mouseenterobject == this.body.prev_button; }
        }

        /// <summary>
        /// 上一组按钮鼠标是否已进入
        /// </summary>
        [Browsable(false)]
        public bool PrevGroupButtonIsMouseEnter
        {
            get { return this.mouseenterobject == this.body.prevgroup_button; }
        }

        /// <summary>
        /// 下一页按钮鼠标是否已进入
        /// </summary>
        [Browsable(false)]
        public bool NextButtonIsMouseEnter
        {
            get { return this.mouseenterobject == this.body.next_button; }
        }

        /// <summary>
        /// 下一组按钮鼠标是否已进入
        /// </summary>
        [Browsable(false)]
        public bool NextGroupButtonIsMouseEnter
        {
            get { return this.mouseenterobject == this.body.nextgroup_button; }
        }

        /// <summary>
        /// 最后一页按钮鼠标是否已进入
        /// </summary>
        [Browsable(false)]
        public bool LastButtonIsMouseEnter
        {
            get { return this.mouseenterobject == this.body.last_button; }
        }

        /// <summary>
        /// 鼠标是否已进入页码,没有返回null
        /// </summary>
        [Browsable(false)]
        public int? PaginationIsMouseEnter
        {
            get
            {
                for (int i = this.body.numbers.Count - 1; i >= 0; i--)
                {
                    if (this.mouseenterobject == this.body.numbers[i])
                        return int.Parse(this.body.numbers[i].str);
                }

                return null;
            }
        }

        #endregion

        #region 重写属性

        protected override Size DefaultSize
        {
            get { return new Size(460, 47); }
        }

        protected override ImeMode DefaultImeMode
        {
            get { return ImeMode.Disable; }
        }

        public override Font Font
        {
            get { return base.Font; }
            set
            {
                base.Font = value;
                this.SetBoundsCore(this.Location.X, this.Location.Y, this.Width, this.Height, BoundsSpecified.Size);
            }
        }

        #endregion

        #region 停用属性

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public new Padding Padding
        {
            get { return base.Padding; }
            set { base.Padding = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public new bool TabStop
        {
            get { return base.TabStop; }
            set { base.TabStop = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override string Text
        {
            get { return base.Text; }
            set { base.Text = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override RightToLeft RightToLeft
        {
            get { return base.RightToLeft; }
            set { base.RightToLeft = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new ImeMode ImeMode
        {
            get { return base.ImeMode; }
            set { base.ImeMode = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override Image BackgroundImage
        {
            get { return base.BackgroundImage; }
            set { base.BackgroundImage = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override ImageLayout BackgroundImageLayout
        {
            get { return base.BackgroundImageLayout; }
            set { base.BackgroundImageLayout = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override Color BackColor
        {
            get { return this.StyleAppearance.BackColor; }
            set { }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override Color ForeColor
        {
            get { return this.StyleAppearance.RecordDescriptionColor; }
            set { }
        }

        #endregion

        #region 字段

        /// <summary>
        /// 当前鼠标已按下的对象
        /// </summary>
        private object mousedownobject = null;
        /// <summary>
        /// 当前鼠标已进入的对象
        /// </summary>
        private object mouseenterobject = null;

        /// <summary>
        /// 页码显示默认文本
        /// </summary>
        private string defaultPaginationText = "首页|上一页|...|...|下一页|尾页|当前共有[*]条";

        /// <summary>
        /// 元素信息
        /// </summary>
        private PaginationBarBody body = new PaginationBarBody();

        #endregion

        public PaginationBar()
        {
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            SetStyle(ControlStyles.ResizeRedraw, true);
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            SetStyle(ControlStyles.StandardClick, false);//自定义单击事件逻辑
            SetStyle(ControlStyles.StandardDoubleClick, false);//停用双加事件

            this.TabStop = false;
            this.InitializeElement();
            this.OnSkinChanged();

        }

        #region 重写

        protected override void OnScaleDpiChangedInitialize()
        {
            this.SetBoundsCore(this.Location.X, this.Location.Y, this.Width, this.Height, BoundsSpecified.Size);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            Graphics g = e.Graphics;

            Color back_color = this.BackColor;
            Pen commom_pen = new Pen(Color.White);
            SolidBrush commom_sb = new SolidBrush(Color.White);

            if (this.body.page_description.visible)
            {
                commom_sb.Color = this.StyleAppearance.PageDescriptionColor;
                g.DrawString(this.body.page_description.str, this.Font, commom_sb, new Point(this.body.page_description.rect.X, this.body.page_description.rect.Y + (this.body.page_description.rect.Height - this.body.page_description.size.Height) / 2), StringFormat.GenericTypographic);
            }

            if (this.body.last_button.visible)
            {
                StyleAppearanceObject.ButtonsAppearanceObject.ItemAppearanceObject itemAppearance = this.LastButtonIsMouseEnter ? this.StyleAppearance.FLButton.Enter : this.StyleAppearance.FLButton.Normal;
                Point text_point = new Point(this.body.last_button.rect.X + (this.body.last_button.rect.Width - this.body.last_button.size.Width) / 2, this.body.last_button.rect.Y + (this.body.last_button.rect.Height - this.body.last_button.size.Height) / 2);

                this.DrawRoundCornerRectangle(g, this.body.last_button.rect, itemAppearance.BackColor, back_color, commom_pen, commom_sb);
                commom_sb.Color = itemAppearance.TextColor;
                g.DrawString(body.last_button.str, this.Font, commom_sb, text_point, StringFormat.GenericTypographic);
            }

            if (this.body.next_button.visible)
            {
                StyleAppearanceObject.ButtonsAppearanceObject.ItemAppearanceObject itemAppearance = this.NextButtonIsMouseEnter ? this.StyleAppearance.PNButton.Enter : this.StyleAppearance.PNButton.Normal;
                Point text_point = new Point(this.body.next_button.rect.X + (this.body.next_button.rect.Width - this.body.next_button.size.Width) / 2, this.body.next_button.rect.Y + (this.body.next_button.rect.Height - this.body.next_button.size.Height) / 2);

                this.DrawRoundCornerRectangle(g, this.body.next_button.rect, itemAppearance.BackColor, back_color, commom_pen, commom_sb);
                commom_sb.Color = itemAppearance.TextColor;
                g.DrawString(body.next_button.str, this.Font, commom_sb, text_point, StringFormat.GenericTypographic);

            }

            if (this.body.nextgroup_button.visible)
            {
                StyleAppearanceObject.ButtonsAppearanceObject.ItemAppearanceObject itemAppearance = this.NextGroupButtonIsMouseEnter ? this.StyleAppearance.GButton.Enter : this.StyleAppearance.GButton.Normal;
                Point text_point = new Point(this.body.nextgroup_button.rect.X + (this.body.nextgroup_button.rect.Width - this.body.nextgroup_button.size.Width) / 2, this.body.nextgroup_button.rect.Y + (this.body.nextgroup_button.rect.Height - this.body.nextgroup_button.size.Height) / 2);

                this.DrawRoundCornerRectangle(g, this.body.nextgroup_button.rect, itemAppearance.BackColor, back_color, commom_pen, commom_sb);
                commom_sb.Color = itemAppearance.TextColor;
                g.DrawString(this.body.nextgroup_button.str, this.Font, commom_sb, text_point, StringFormat.GenericTypographic);

            }

            for (int i = this.body.numbers.Count - 1; i >= 0; i--)
            {
                PaginationNumberElement element = this.body.numbers[i];

                Color back_commom_color = this.StyleAppearance.Pagination.Normal.BackColor;
                Color text_commom_color = this.StyleAppearance.Pagination.Normal.TextColor;
                if (this.CurrentPage == int.Parse(element.str))
                {
                    back_commom_color = this.StyleAppearance.Pagination.Current.BackColor;
                    text_commom_color = this.StyleAppearance.Pagination.Current.TextColor;
                }
                else if (this.mouseenterobject == element)
                {
                    back_commom_color = this.StyleAppearance.Pagination.Enter.BackColor;
                    text_commom_color = this.StyleAppearance.Pagination.Enter.TextColor;
                }
                this.DrawRoundCornerRectangle(g, element.rect, back_commom_color, back_color, commom_pen, commom_sb);
                commom_sb.Color = text_commom_color;
                g.DrawString(element.str, this.Font, commom_sb, new Point(element.rect.X + (element.rect.Width - element.size.Width) / 2, element.rect.Y + (element.rect.Height - element.size.Height) / 2), StringFormat.GenericTypographic);

            }

            if (this.body.prevgroup_button.visible)
            {
                StyleAppearanceObject.ButtonsAppearanceObject.ItemAppearanceObject itemAppearance = this.PrevGroupButtonIsMouseEnter ? this.StyleAppearance.GButton.Enter : this.StyleAppearance.GButton.Normal;
                Point text_point = new Point(this.body.prevgroup_button.rect.X + (this.body.prevgroup_button.rect.Width - this.body.prevgroup_button.size.Width) / 2, this.body.prevgroup_button.rect.Y + (this.body.prevgroup_button.rect.Height - this.body.prevgroup_button.size.Height) / 2);

                this.DrawRoundCornerRectangle(g, this.body.prevgroup_button.rect, itemAppearance.BackColor, back_color, commom_pen, commom_sb);
                commom_sb.Color = itemAppearance.TextColor;
                g.DrawString(this.body.prevgroup_button.str, this.Font, commom_sb, text_point, StringFormat.GenericTypographic);

            }

            if (this.body.prev_button.visible)
            {
                StyleAppearanceObject.ButtonsAppearanceObject.ItemAppearanceObject itemAppearance = this.PrevButtonIsMouseEnter ? this.StyleAppearance.PNButton.Enter : this.StyleAppearance.PNButton.Normal;
                Point text_point = new Point(this.body.prev_button.rect.X + (this.body.prev_button.rect.Width - this.body.prev_button.size.Width) / 2, this.body.prev_button.rect.Y + (this.body.prev_button.rect.Height - this.body.prev_button.size.Height) / 2);

                this.DrawRoundCornerRectangle(g, this.body.prev_button.rect, itemAppearance.BackColor, back_color, commom_pen, commom_sb);
                commom_sb.Color = itemAppearance.TextColor;
                g.DrawString(body.prev_button.str, this.Font, commom_sb, text_point, StringFormat.GenericTypographic);

            }

            if (this.body.first_button.visible)
            {
                StyleAppearanceObject.ButtonsAppearanceObject.ItemAppearanceObject itemAppearance = this.FirstButtonIsMouseEnter ? this.StyleAppearance.FLButton.Enter : this.StyleAppearance.FLButton.Normal;
                Point text_point = new Point(this.body.first_button.rect.X + (this.body.first_button.rect.Width - this.body.first_button.size.Width) / 2, this.body.first_button.rect.Y + (this.body.first_button.rect.Height - this.body.first_button.size.Height) / 2);

                this.DrawRoundCornerRectangle(g, this.body.first_button.rect, itemAppearance.BackColor, back_color, commom_pen, commom_sb);
                commom_sb.Color = itemAppearance.TextColor;
                g.DrawString(body.first_button.str, this.Font, commom_sb, text_point, StringFormat.GenericTypographic);

            }

            if (this.body.record_description.visible)
            {
                commom_sb.Color = this.StyleAppearance.RecordDescriptionColor;
                g.DrawString(this.body.record_description.str, this.Font, commom_sb, new Point(this.body.record_description.rect.X, this.body.record_description.rect.Y + (this.body.record_description.rect.Height - this.body.record_description.size.Height) / 2), StringFormat.GenericTypographic);
            }

        }

        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);

            this.mousedownobject = null;
            this.mouseenterobject = null;
            this.Invalidate();
        }

        protected override void OnEnabledChanged(EventArgs e)
        {
            base.OnEnabledChanged(e);

            if (!this.Enabled)
            {
                this.mousedownobject = null;
                this.mouseenterobject = null;
                this.Invalidate();
            }
        }

        protected override void OnVisibleChanged(EventArgs e)
        {
            base.OnVisibleChanged(e);

            if (!this.Visible)
            {
                this.mousedownobject = null;
                this.mouseenterobject = null;
                this.Invalidate();
            }
        }

        protected override void OnParentChanged(EventArgs e)
        {
            base.OnParentChanged(e);

            if (this.Parent == null)
            {
                this.mousedownobject = null;
                this.mouseenterobject = null;
                this.Invalidate();
            }
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (!this.Focused)
            {
                this.Focus();
            }

            if (e.Button == MouseButtons.Left)
            {
                if (this.body.last_button.visible && this.body.last_button.rect.Contains(e.Location))
                {
                    this.mousedownobject = this.body.last_button;
                }
                else if (this.body.next_button.visible && this.body.next_button.rect.Contains(e.Location))
                {
                    this.mousedownobject = this.body.next_button;
                }
                else if (this.body.nextgroup_button.visible && this.body.nextgroup_button.rect.Contains(e.Location))
                {
                    this.mousedownobject = this.body.nextgroup_button;
                }
                else if (this.body.prevgroup_button.visible && this.body.prevgroup_button.rect.Contains(e.Location))
                {
                    this.mousedownobject = this.body.prevgroup_button;
                }
                else if (this.body.prev_button.visible && this.body.prev_button.rect.Contains(e.Location))
                {
                    this.mousedownobject = this.body.prev_button;
                }
                else if (this.body.first_button.visible && this.body.first_button.rect.Contains(e.Location))
                {
                    this.mousedownobject = this.body.first_button;
                }
                else
                {
                    for (int i = 0; i < this.body.numbers.Count; i++)
                    {
                        if (this.body.numbers[i].rect.Contains(e.Location))
                        {
                            this.mousedownobject = this.body.numbers[i];
                            break;
                        }
                    }

                }
            }

            base.OnMouseDown(e);
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (this.mousedownobject != null)
                {
                    if (this.body.last_button.visible && this.body.last_button.rect.Contains(e.Location))
                    {
                        if (this.mouseenterobject == this.body.last_button)
                        {
                            if (this.currentPage != this.totalPages)
                            {
                                this.OnPaginationChanged(new PaginationBarChangedEventArgs(this.totalPages));
                            }
                        }
                    }
                    else if (this.body.next_button.visible && this.body.next_button.rect.Contains(e.Location))
                    {
                        if (this.mouseenterobject == this.body.next_button)
                        {
                            if (this.currentPage < this.totalPages)
                            {
                                this.OnPaginationChanged(new PaginationBarChangedEventArgs(this.currentPage + 1));
                            }
                        }
                    }
                    else if (this.body.nextgroup_button.visible && this.body.nextgroup_button.rect.Contains(e.Location))
                    {
                        if (this.mouseenterobject == this.body.nextgroup_button)
                        {
                            int index = Math.Min(this.totalPages, this.currentPage + this.limitPage);
                            if (this.currentPage != index)
                            {
                                this.OnPaginationChanged(new PaginationBarChangedEventArgs(index));
                            }
                        }
                    }
                    else if (this.body.prevgroup_button.visible && this.body.prevgroup_button.rect.Contains(e.Location))
                    {
                        if (this.mouseenterobject == this.body.prevgroup_button)
                        {
                            int index = Math.Max(1, this.currentPage - this.limitPage);
                            if (this.currentPage != index)
                            {
                                this.OnPaginationChanged(new PaginationBarChangedEventArgs(index));
                            }
                        }
                    }
                    else if (this.body.prev_button.visible && this.body.prev_button.rect.Contains(e.Location))
                    {
                        if (this.mouseenterobject == this.body.prev_button)
                        {
                            if (this.currentPage > 1)
                            {
                                this.OnPaginationChanged(new PaginationBarChangedEventArgs(this.currentPage - 1));
                            }
                        }
                    }
                    else if (this.body.first_button.visible && this.body.first_button.rect.Contains(e.Location))
                    {
                        if (this.mouseenterobject == this.body.first_button)
                        {
                            if (this.currentPage != 1)
                            {
                                this.OnPaginationChanged(new PaginationBarChangedEventArgs(1));
                            }
                        }
                    }
                    else
                    {
                        for (int i = 0; i < this.body.numbers.Count; i++)
                        {
                            if (this.body.numbers[i].rect.Contains(e.Location))
                            {
                                if (this.mouseenterobject == this.body.numbers[i])
                                {
                                    this.OnPaginationChanged(new PaginationBarChangedEventArgs(int.Parse(this.body.numbers[i].str)));
                                }
                                break;
                            }
                        }

                    }
                }
            }

            this.mousedownobject = null;

            base.OnMouseUp(e);
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            if (this.mousedownobject == null)
            {
                if (this.body.last_button.visible && this.body.last_button.rect.Contains(e.Location))
                {
                    if (this.mouseenterobject != this.body.last_button)
                    {
                        this.mouseenterobject = this.body.last_button;
                        this.Invalidate();
                    }
                }
                else if (this.body.next_button.visible && this.body.next_button.rect.Contains(e.Location))
                {
                    if (this.mouseenterobject != this.body.next_button)
                    {
                        this.mouseenterobject = this.body.next_button;
                        this.Invalidate();
                    }
                }
                else if (this.body.nextgroup_button.visible && this.body.nextgroup_button.rect.Contains(e.Location))
                {
                    if (this.mouseenterobject != this.body.nextgroup_button)
                    {
                        this.mouseenterobject = this.body.nextgroup_button;
                        this.Invalidate();
                    }
                }
                else if (this.body.prevgroup_button.visible && this.body.prevgroup_button.rect.Contains(e.Location))
                {
                    if (this.mouseenterobject != this.body.prevgroup_button)
                    {
                        this.mouseenterobject = this.body.prevgroup_button;
                        this.Invalidate();
                    }
                }
                else if (this.body.prev_button.visible && this.body.prev_button.rect.Contains(e.Location))
                {
                    if (this.mouseenterobject != this.body.prev_button)
                    {
                        this.mouseenterobject = this.body.prev_button;
                        this.Invalidate();
                    }
                }
                else if (this.body.first_button.visible && this.body.first_button.rect.Contains(e.Location))
                {
                    if (this.mouseenterobject != this.body.first_button)
                    {
                        this.mouseenterobject = this.body.first_button;
                        this.Invalidate();
                    }
                }
                else
                {
                    for (int i = 0; i < this.body.numbers.Count; i++)
                    {
                        if (this.body.numbers[i].rect.Contains(e.Location))
                        {
                            if (this.mouseenterobject != this.body.numbers[i])
                            {
                                this.mouseenterobject = this.body.numbers[i];
                                this.Invalidate();
                            }
                            break;
                        }
                    }

                }
            }
        }

        protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
        {
            base.SetBoundsCore(x, y, width, this.GetControlAutoHeight(), specified);

            this.InitializeElement();
            this.Invalidate();
        }

        #endregion

        #region 虚方法

        protected virtual void OnPaginationChanged(PaginationBarChangedEventArgs e)
        {
            PaginationChangedEventHandler handler = Events[EventPaginationChanged] as PaginationChangedEventHandler;
            if (handler != null)
            {
                handler(this, e);
            }
        }

        #endregion

        #region 公开方法

        /// <summary>
        /// 初始化控件内部元素布局
        /// </summary>
        public void InitializeElement()
        {
            // 同步页码元素
            int limitPage_tmp = Math.Min(this.limitPage, this.totalPages);
            int center_index = (int)Math.Ceiling(limitPage_tmp / 2f);
            int display_start_index = Math.Min(this.totalPages - limitPage_tmp + 1, Math.Max(1, this.currentPage - (center_index - 1)));
            List<PaginationNumberElement> numbers_tmp = new List<PaginationNumberElement>();
            for (int i = 0; i < limitPage_tmp; i++)
            {
                numbers_tmp.Add(new PaginationNumberElement() { str = (display_start_index + i).ToString() });
            }
            this.body.numbers = numbers_tmp;

            string[] strArr = this.GetPaginationText();
            this.body.record_description.str = strArr[0].Replace("[*]", this.totalRecords.ToString());
            this.body.record_description.visible = (this.RecordDescriptionVisible);
            this.body.first_button.str = strArr[1];
            this.body.first_button.visible = (this.FLButtonVisible && this.totalRecords > 0);
            this.body.prev_button.str = strArr[2];
            this.body.prev_button.visible = (this.PNButtonVisible && this.totalRecords > 0);
            this.body.prevgroup_button.str = strArr[3];
            this.body.prevgroup_button.visible = (this.GButtonVisible && this.totalRecords > 0 && this.body.numbers.Count > 0 && int.Parse(this.body.numbers[0].str) > 1);
            this.body.nextgroup_button.str = strArr[4];
            this.body.nextgroup_button.visible = (this.GButtonVisible && this.totalPages > 0 && this.body.numbers.Count > 0 && int.Parse(this.body.numbers[this.body.numbers.Count - 1].str) < this.totalPages);
            this.body.next_button.str = strArr[5];
            this.body.next_button.visible = (this.PNButtonVisible && this.totalRecords > 0);
            this.body.last_button.str = strArr[6];
            this.body.last_button.visible = (this.FLButtonVisible && this.totalRecords > 0);
            this.body.page_description.str = strArr[7].Replace("[*]", this.totalPages.ToString());
            this.body.page_description.visible = (this.RecordDescriptionVisible && this.PageDescriptionVisible && this.totalRecords > 0) || (!this.RecordDescriptionVisible && this.PageDescriptionVisible);



            // 初始化页码元素Rectangle
            IntPtr hDC = IntPtr.Zero;
            Graphics g = null;
            ControlHelper.GetWindowClientGraphics(this.Handle, out g, out hDC);

            Padding scale_contentPadding = new Padding((int)Math.Ceiling(this.ContentPadding.Left * this.ScaleDpi), (int)Math.Ceiling(this.ContentPadding.Top * this.ScaleDpi), (int)Math.Ceiling(this.ContentPadding.Right * this.ScaleDpi), (int)Math.Ceiling(this.ContentPadding.Bottom * this.ScaleDpi));
            NativeMethods.TEXTMETRIC font_metrics = ControlHelper.GetFontMetrics(this.Handle, this.Font);
            int pagination_topbottom_padding = font_metrics.GetFontStereotypesMargim() * 2;
            int pagination_leftright_padding = font_metrics.GetFontStereotypesMargim() * 3;
            int pagination_height = pagination_topbottom_padding + font_metrics.GetFontStereotypesHeight() + pagination_topbottom_padding;
            int pagination_min_width = pagination_leftright_padding + font_metrics.GetFontStereotypesHeight() + pagination_leftright_padding;
            int x = this.ClientRectangle.Right - scale_contentPadding.Right;

            if (this.body.page_description.visible)
            {
                this.body.page_description.size = new Size((int)Math.Ceiling(g.MeasureString(this.body.page_description.str, this.Font, int.MaxValue, StringFormat.GenericTypographic).Width), font_metrics.GetFontRealHeight());
                this.body.page_description.rect = new Rectangle(x - this.body.page_description.size.Width, this.ClientRectangle.Y + scale_contentPadding.Top, this.body.page_description.size.Width, pagination_height);
                x -= (this.body.page_description.rect.Width + font_metrics.GetFontStereotypesMargim() * 2);
            }
            else
            {
                this.body.page_description.rect = new Rectangle(x, this.ClientRectangle.Y, 0, pagination_height);
                x -= font_metrics.GetFontStereotypesMargim() * 2;
            }

            if (this.body.last_button.visible)
            {
                x -= font_metrics.GetFontStereotypesMargim();
                this.body.last_button.size = new Size((int)Math.Ceiling(g.MeasureString(body.last_button.str, this.Font, int.MaxValue, StringFormat.GenericTypographic).Width), font_metrics.GetFontRealHeight());
                int pagination_width = Math.Max(pagination_min_width, (pagination_leftright_padding + this.body.last_button.size.Width + pagination_leftright_padding));
                this.body.last_button.rect = new Rectangle(x - pagination_width, this.ClientRectangle.Y + scale_contentPadding.Top, pagination_width, pagination_height);
                x -= this.body.last_button.rect.Width;
            }
            else
            {
                this.body.last_button.rect = new Rectangle(x, this.ClientRectangle.Y + scale_contentPadding.Top, 0, pagination_height);
            }

            if (this.body.next_button.visible)
            {
                x -= font_metrics.GetFontStereotypesMargim();
                this.body.next_button.size = new Size((int)Math.Ceiling(g.MeasureString(body.next_button.str, this.Font, int.MaxValue, StringFormat.GenericTypographic).Width), font_metrics.GetFontRealHeight());
                int pagination_width = Math.Max(pagination_min_width, (pagination_leftright_padding + this.body.next_button.size.Width + pagination_leftright_padding));
                this.body.next_button.rect = new Rectangle(x - pagination_width, this.ClientRectangle.Y + scale_contentPadding.Top, pagination_width, pagination_height);
                x -= this.body.next_button.rect.Width;
            }
            else
            {
                this.body.next_button.rect = new Rectangle(x, this.ClientRectangle.Y + scale_contentPadding.Top, 0, pagination_height);
            }

            if (this.body.nextgroup_button.visible)
            {
                x -= font_metrics.GetFontStereotypesMargim();
                this.body.nextgroup_button.size = new Size((int)Math.Ceiling(g.MeasureString(this.body.nextgroup_button.str, this.Font, int.MaxValue, StringFormat.GenericTypographic).Width), font_metrics.GetFontRealHeight());
                int pagination_width = Math.Max(pagination_min_width, (pagination_leftright_padding + this.body.nextgroup_button.size.Width + pagination_leftright_padding));
                this.body.nextgroup_button.rect = new Rectangle(x - pagination_width, this.ClientRectangle.Y + scale_contentPadding.Top, pagination_width, pagination_height);
                x -= this.body.nextgroup_button.rect.Width;
            }
            else
            {
                this.body.nextgroup_button.rect = new Rectangle(x, this.ClientRectangle.Y + scale_contentPadding.Top, 0, pagination_height);
            }

            for (int i = this.body.numbers.Count - 1; i >= 0; i--)
            {
                x -= font_metrics.GetFontStereotypesMargim();
                this.body.numbers[i].size = new Size((int)Math.Ceiling(g.MeasureString(this.body.numbers[i].str, this.Font, int.MaxValue, StringFormat.GenericTypographic).Width), font_metrics.GetFontRealHeight());
                int pagination_width = Math.Max(pagination_min_width, (pagination_leftright_padding + this.body.numbers[i].size.Width + pagination_leftright_padding));
                this.body.numbers[i].rect = new Rectangle(x - pagination_width, this.ClientRectangle.Y + scale_contentPadding.Top, pagination_width, pagination_height);
                x -= this.body.numbers[i].rect.Width;
            }

            if (this.body.prevgroup_button.visible)
            {
                x -= font_metrics.GetFontStereotypesMargim();
                this.body.prevgroup_button.size = new Size((int)Math.Ceiling(g.MeasureString(this.body.prevgroup_button.str, this.Font, int.MaxValue, StringFormat.GenericTypographic).Width), font_metrics.GetFontRealHeight());
                int pagination_width = Math.Max(pagination_min_width, (pagination_leftright_padding + this.body.prevgroup_button.size.Width + pagination_leftright_padding));
                this.body.prevgroup_button.rect = new Rectangle(x - pagination_width, this.ClientRectangle.Y + scale_contentPadding.Top, pagination_width, pagination_height);
                x -= this.body.prevgroup_button.rect.Width;
            }
            else
            {
                this.body.prevgroup_button.rect = new Rectangle(x, this.ClientRectangle.Y + scale_contentPadding.Top, 0, pagination_height);
            }

            if (this.body.prev_button.visible)
            {
                x -= font_metrics.GetFontStereotypesMargim();
                this.body.prev_button.size = new Size((int)Math.Ceiling(g.MeasureString(body.prev_button.str, this.Font, int.MaxValue, StringFormat.GenericTypographic).Width), font_metrics.GetFontRealHeight());
                int pagination_width = Math.Max(pagination_min_width, (pagination_leftright_padding + this.body.prev_button.size.Width + pagination_leftright_padding));
                this.body.prev_button.rect = new Rectangle(x - pagination_width, this.ClientRectangle.Y + scale_contentPadding.Top, pagination_width, pagination_height);
                x -= this.body.prev_button.rect.Width;
            }
            else
            {
                this.body.prev_button.rect = new Rectangle(x, this.ClientRectangle.Y + scale_contentPadding.Top, 0, pagination_height);
            }

            if (this.body.first_button.visible)
            {
                x -= font_metrics.GetFontStereotypesMargim();
                this.body.first_button.size = new Size((int)Math.Ceiling(g.MeasureString(body.first_button.str, this.Font, int.MaxValue, StringFormat.GenericTypographic).Width), font_metrics.GetFontRealHeight());
                int pagination_width = Math.Max(pagination_min_width, (pagination_leftright_padding + this.body.first_button.size.Width + pagination_leftright_padding));
                this.body.first_button.rect = new Rectangle(x - pagination_width, this.ClientRectangle.Y + scale_contentPadding.Top, pagination_width, pagination_height);
                x -= this.body.first_button.rect.Width;
            }
            else
            {
                this.body.first_button.rect = new Rectangle(x, this.ClientRectangle.Y + scale_contentPadding.Top, 0, pagination_height);
            }

            if (this.body.record_description.visible)
            {
                x -= pagination_leftright_padding;
                this.body.record_description.size = new Size((int)Math.Ceiling(g.MeasureString(this.body.record_description.str, this.Font, int.MaxValue, StringFormat.GenericTypographic).Width), font_metrics.GetFontRealHeight());
                this.body.record_description.rect = new Rectangle(x - this.body.record_description.size.Width, this.ClientRectangle.Y + scale_contentPadding.Top, this.body.record_description.size.Width, pagination_height);
                x -= this.body.record_description.rect.Width;
            }
            else
            {
                this.body.record_description.rect = new Rectangle(x, this.ClientRectangle.Y + scale_contentPadding.Top, 0, pagination_height);
            }


            g.Dispose();
            NativeMethods.ReleaseDC(this.Handle, hDC);
        }

        /// <summary>
        /// 设置页码导航
        /// </summary>
        /// <param name="limitPage">导航一次最多显示多少个页码（建议为奇数，最小值为5）</param>
        /// <param name="totalRecords">总记录数</param>
        /// <param name="pageSize">多少条记录为一页（最小值为1）</param>
        /// <param name="currentPage">当前页码索引（从1开始）</param>
        public void SetPagination(int limitPage, int totalRecords, int pageSize, int currentPage)
        {
            limitPage = Math.Max(5, limitPage);
            totalRecords = Math.Max(0, totalRecords);
            pageSize = Math.Max(1, pageSize);
            int pages = (int)Math.Ceiling(totalRecords / (float)pageSize);

            if (totalRecords == 0)
            {
                currentPage = 0;
            }
            if ((totalRecords == 0 && currentPage != 0) || (totalRecords != 0 && (currentPage <= 0 || currentPage > pages)))
            {
                throw new Exception("currentPage超出范围");
            }

            this.limitPage = limitPage;
            this.totalRecords = totalRecords;
            this.pageSize = pageSize;
            this.totalPages = pages;
            this.currentPage = currentPage;

            this.InitializeElement();
            this.Invalidate();
        }

        /// <summary>
        /// 鼠标是否进入对象
        /// </summary>
        /// <param name="obj">对象</param>
        /// <returns></returns>
        internal bool IsMouseEnter(object obj)
        {
            return (obj != null && this.mouseenterobject == obj);
        }

        #endregion

        #region 私有方法

        /// <summary>
        /// 绘制Rectangle 1个像素边框（圆角边框半径为3个像素）
        /// </summary>
        /// <param name="g">要绘制边框的控件画布</param>
        /// <param name="rect">要绘制rect</param>
        /// <param name="backColor">背景色</param>
        /// <param name="backOverColor">控件背景色（圆角边框平滑过度颜色）</param>
        /// <param name="commom_pen">通用画笔</param>
        /// <param name="commom_sb">通用画笔</param>
        private void DrawRoundCornerRectangle(Graphics g, Rectangle rect, Color backColor, Color backOverColor, Pen commom_pen, SolidBrush commom_sb)
        {
            if (backColor.A==byte.MinValue)
                return;

            SmoothingMode smoothingMode = g.SmoothingMode;
            CompositingMode compositingMode = g.CompositingMode;
            CompositingQuality compositingQuality = g.CompositingQuality;
            InterpolationMode interpolationMode = g.InterpolationMode;

            g.SmoothingMode = SmoothingMode.None;
            g.CompositingMode = CompositingMode.SourceCopy;
            g.CompositingQuality = CompositingQuality.Default;
            g.InterpolationMode = InterpolationMode.Default;

            //背景
            commom_sb.Color = backColor;
            g.FillPolygon(commom_sb, new Point[] {
                   new Point(rect.Left,rect.Top+1),
                   new Point(rect.Left+1,rect.Top+1),
                   new Point(rect.Left+1,rect.Top),

                   new Point(rect.Right-1,rect.Top),
                   new Point(rect.Right-1,rect.Top+1),
                   new Point(rect.Right,rect.Top+1),

                   new Point(rect.Right,rect.Bottom-1),
                   new Point(rect.Right-1,rect.Bottom-1),
                   new Point(rect.Right-1,rect.Bottom),

                   new Point(rect.Left+1,rect.Bottom-1),
                   new Point(rect.Left+1,rect.Bottom-1-1),
                   new Point(rect.Left,rect.Bottom-1-1),
                 });

            //背景圆角外平滑过度
            commom_pen.Color = Color.FromArgb(backColor.R + (backOverColor.R - backColor.R) / 4, backColor.G + (backOverColor.G - backColor.G) / 4, backColor.B + (backOverColor.B - backColor.B) / 4);
            g.DrawLine(commom_pen, new Point(rect.Left, rect.Top + 1), new Point(rect.Left + 1, rect.Top));
            g.DrawLine(commom_pen, new Point(rect.Right - 1 - 1, rect.Top), new Point(rect.Right - 1, rect.Top + 1));
            g.DrawLine(commom_pen, new Point(rect.Right - 1, rect.Bottom - 1 - 1), new Point(rect.Right - 1 - 1, rect.Bottom - 1));
            g.DrawLine(commom_pen, new Point(rect.Left + 1, rect.Bottom - 1), new Point(rect.Left, rect.Bottom - 1 - 1));



            g.SmoothingMode = smoothingMode;
            g.CompositingMode = compositingMode;
            g.CompositingQuality = compositingQuality;
            g.InterpolationMode = interpolationMode;
        }

        /// <summary>
        /// 获取页码显示文本
        /// </summary>
        /// <returns></returns>
        private string[] GetPaginationText()
        {
            string[] strArr = this.Template.Split(new char[] { '|' }, StringSplitOptions.None);
            if (strArr.Length != 8)
            {
                strArr = this.defaultPaginationText.Split(new char[] { '|' }, StringSplitOptions.None);
            }
            for (int i = 0; i < strArr.Length; i++)
            {
                strArr[i] = strArr[i].Trim();
            }
            return strArr;
        }

        /// <summary>
        /// 根据设置计算控件高度
        /// </summary>
        /// <returns></returns>
        private int GetControlAutoHeight()
        {
            Padding scale_contentPadding = new Padding((int)Math.Ceiling(this.ContentPadding.Left * this.ScaleDpi), (int)Math.Ceiling(this.ContentPadding.Top * this.ScaleDpi), (int)Math.Ceiling(this.ContentPadding.Right * this.ScaleDpi), (int)Math.Ceiling(this.ContentPadding.Bottom * this.ScaleDpi));
            NativeMethods.TEXTMETRIC font_metrics = ControlHelper.GetFontMetrics(this.Handle, this.Font);
            return scale_contentPadding.Top + font_metrics.GetFontStereotypesMargim() * 2 + font_metrics.GetFontStereotypesHeight() + font_metrics.GetFontStereotypesMargim() * 2 + scale_contentPadding.Bottom;
        }

        #endregion

        #region 枚举

        /// <summary>
        /// 页码按钮元素类型
        /// </summary>
        private enum PaginationButtonElementType
        {
            /// <summary>
            /// 首页
            /// </summary>
            First,
            /// <summary>
            /// 上一页
            /// </summary>
            Prev,
            /// <summary>
            /// 上一组
            /// </summary>
            PrevGroup,
            /// <summary>
            /// 下一组
            /// </summary>
            NextGroup,
            /// <summary>
            /// 下一页
            /// </summary>
            Next,
            /// <summary>
            /// 尾页
            /// </summary>
            Last,
            /// <summary>
            ///描述 
            /// </summary>
            Description
        }

        #endregion

        #region 类

        private class PaginationBarBody
        {
            /// <summary>
            /// 记录数描述
            /// </summary>
            public PaginationButtonElement record_description = new PaginationButtonElement();
            /// <summary>
            /// 首页
            /// </summary>
            public PaginationButtonElement first_button = new PaginationButtonElement();
            /// <summary>
            /// 上一页
            /// </summary>
            public PaginationButtonElement prev_button = new PaginationButtonElement();
            /// <summary>
            /// 上一组
            /// </summary>
            public PaginationButtonElement prevgroup_button = new PaginationButtonElement();
            /// <summary>
            /// 下一组
            /// </summary>
            public List<PaginationNumberElement> numbers = new List<PaginationNumberElement>();
            /// <summary>
            /// 下一页
            /// </summary>
            public PaginationButtonElement nextgroup_button = new PaginationButtonElement();
            /// <summary>
            /// 尾页
            /// </summary>
            public PaginationButtonElement next_button = new PaginationButtonElement();
            /// <summary>
            /// 
            /// </summary>
            public PaginationButtonElement last_button = new PaginationButtonElement();
            /// <summary>
            /// 页数描述
            /// </summary>
            public PaginationButtonElement page_description = new PaginationButtonElement();
        }

        /// <summary>
        /// 页码索引元素
        /// </summary>
        private class PaginationNumberElement
        {
            /// <summary>
            /// 元素文本
            /// </summary>
            public string str { get; set; }

            /// <summary>
            /// 元素文本Size
            /// </summary>
            public Size size { get; set; }

            /// <summary>
            /// 元素rect
            /// </summary>
            public Rectangle rect { get; set; }

        }

        /// <summary>
        /// 页码按钮元素
        /// </summary>
        private class PaginationButtonElement
        {
            /// <summary>
            /// 元素类型
            /// </summary>
            public PaginationButtonElementType type { get; set; }

            /// <summary>
            /// 是否显示
            /// </summary>
            public bool visible { get; set; }

            /// <summary>
            /// 元素文本
            /// </summary>
            public string str { get; set; }

            /// <summary>
            /// 元素文本Size
            /// </summary>
            public Size size { get; set; }

            /// <summary>
            /// 元素rect
            /// </summary>
            public Rectangle rect { get; set; }

        }

        #endregion

        #region 外观

        public class StyleAppearanceObject : AppearanceObjectBase
        {
            internal StyleAppearanceObject(ISkinObject owner, AppearanceObjectBase parent) : base(owner, parent) { }

            #region 属性

            private Color skinBackColor = Color.Empty;
            private readonly Color defaultBackColor = SystemColors.Control;
            private Color backColor = Color.Empty;
            /// <summary>
            /// 背景颜色
            /// </summary>
            [Description("背景颜色")]
            [PropertyOrder(-198)]
            [SkinProperty(true, true)]
            public Color BackColor
            {
                get
                {
                    if (this.owner.GetSkinObjectSkinStateCore() && this.skinBackColor != Color.Empty)
                    {
                        return this.skinBackColor;
                    }

                    if (this.backColor != Color.Empty)
                    {
                        return this.backColor;
                    }

                    if (((Control)this.owner).Parent != null)
                    {
                        return ((Control)this.owner).Parent.BackColor;
                    }

                    return this.defaultBackColor;
                }
                set
                {
                    if (this.backColor == value)
                        return;

                    this.backColor = value;
                    this.Invalidate();
                }
            }
            private bool ShouldSerializeBackColor()
            {
                return this.backColor != Color.Empty;
            }
            private void ResetBackColor()
            {
                this.backColor = Color.Empty;
                this.Invalidate();
            }

            private Color skinPageDescriptionColor = Color.Empty;
            private readonly Color defaultPageDescriptionColor = SystemColors.ControlText;
            private Color pageDescriptionColor = Color.Empty;
            /// <summary>
            /// 页数描述文本颜色
            /// </summary>
            [Description("页数描述文本颜色")]
            [PropertyOrder(-196)]
            [SkinProperty(true, true)]
            public Color PageDescriptionColor
            {
                get
                {
                    if (this.owner.GetSkinObjectSkinStateCore() && this.skinPageDescriptionColor != Color.Empty)
                    {
                        return this.skinPageDescriptionColor;
                    }

                    if (this.pageDescriptionColor != Color.Empty)
                    {
                        return this.pageDescriptionColor;
                    }

                    if (((Control)this.owner).Parent != null)
                    {
                        return ((Control)this.owner).Parent.ForeColor;
                    }

                    return this.defaultPageDescriptionColor;
                }
                set
                {
                    if (this.pageDescriptionColor == value)
                        return;

                    this.pageDescriptionColor = value;
                    this.Invalidate();
                }
            }
            private bool ShouldSerializePageDescriptionColor()
            {
                return this.pageDescriptionColor != Color.Empty;
            }
            private void ResetPageDescriptionColor()
            {
                this.pageDescriptionColor = Color.Empty;
                this.Invalidate();
            }

            private Color skinRecordDescriptionColor = Color.Empty;
            private readonly Color defaultRecordDescriptionColor = SystemColors.ControlText;
            private Color recordDescriptionColor = Color.Empty;
            /// <summary>
            /// 页数描述文本颜色
            /// </summary>
            [Description("页数描述文本颜色")]
            [PropertyOrder(-194)]
            [SkinProperty(true, true)]
            public Color RecordDescriptionColor
            {
                get
                {
                    if (this.owner.GetSkinObjectSkinStateCore() && this.skinRecordDescriptionColor != Color.Empty)
                    {
                        return this.skinRecordDescriptionColor;
                    }

                    if (this.recordDescriptionColor != Color.Empty)
                    {
                        return this.recordDescriptionColor;
                    }

                    if (((Control)this.owner).Parent != null)
                    {
                        return ((Control)this.owner).Parent.ForeColor;
                    }

                    return this.defaultRecordDescriptionColor;
                }
                set
                {
                    if (this.recordDescriptionColor == value)
                        return;

                    this.recordDescriptionColor = value;
                    this.Invalidate();
                }
            }
            private bool ShouldSerializeRecordDescriptionColor()
            {
                return this.recordDescriptionColor != Color.Empty;
            }
            private void ResetRecordDescriptionColor()
            {
                this.recordDescriptionColor = Color.Empty;
                this.Invalidate();
            }

            private ButtonsAppearanceObject fLButton;
            /// <summary>
            /// 首页尾页按钮
            /// </summary>
            [Description("首页尾页按钮")]
            [PropertyOrder(-192)]
            [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
            [SkinProperty(true, false)]
            public ButtonsAppearanceObject FLButton
            {
                get
                {
                    if (this.fLButton == null)
                        this.fLButton = new ButtonsAppearanceObject(this.owner, this, SystemColors.GradientActiveCaption, SystemColors.ButtonHighlight, SystemColors.ActiveCaption, SystemColors.ButtonHighlight);
                    return this.fLButton;
                }
            }

            private ButtonsAppearanceObject pNButton;
            /// <summary>
            /// 上一页下一页按钮
            /// </summary>
            [Description("上一页下一页按钮")]
            [PropertyOrder(-190)]
            [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
            [SkinProperty(true, false)]
            public ButtonsAppearanceObject PNButton
            {
                get
                {
                    if (this.pNButton == null)
                        this.pNButton = new ButtonsAppearanceObject(this.owner, this, SystemColors.GradientActiveCaption, SystemColors.ButtonHighlight, SystemColors.ActiveCaption, SystemColors.ButtonHighlight);
                    return this.pNButton;
                }
            }

            private ButtonsAppearanceObject gButton;
            /// <summary>
            /// 上一组下一组按钮
            /// </summary>
            [Description("上一组下一组按钮")]
            [PropertyOrder(-188)]
            [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
            [SkinProperty(true, false)]
            public ButtonsAppearanceObject GButton
            {
                get
                {
                    if (this.gButton == null)
                        this.gButton = new ButtonsAppearanceObject(this.owner, this, Color.Empty, SystemColors.ActiveCaption, Color.Empty, SystemColors.ActiveCaption);
                    return this.gButton;
                }
            }

            private PaginationAppearanceObject pagination;
            /// <summary>
            /// 页码
            /// </summary>
            [Description("页码")]
            [PropertyOrder(-186)]
            [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
            [SkinProperty(true, false)]
            public PaginationAppearanceObject Pagination
            {
                get
                {
                    if (this.pagination == null)
                        this.pagination = new PaginationAppearanceObject(this.owner, this);
                    return this.pagination;
                }
            }

            #endregion

            public class ButtonsAppearanceObject : AppearanceObjectBase
            {
                internal ButtonsAppearanceObject(ISkinObject owner, AppearanceObjectBase parent, Color backNormalColor, Color textNormalColor, Color backEnterColor, Color textEnterColor) : base(owner, parent)
                {
                    this.backNormalColor = backNormalColor;
                    this.textNormalColor = textNormalColor;
                    this.backEnterColor = backEnterColor;
                    this.textEnterColor = textEnterColor;
                }

                #region 属性

                private Color backNormalColor = Color.Empty;
                private Color textNormalColor = Color.Empty;
                private ItemAppearanceObject normal;
                /// <summary>
                /// 正常状态
                /// </summary>
                [Description("正常状态")]
                [PropertyOrder(-194)]
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
                [SkinProperty(true, false)]
                public ItemAppearanceObject Normal
                {
                    get
                    {
                        if (this.normal == null)
                            this.normal = new ItemAppearanceObject(this.owner, this, backNormalColor, textNormalColor);
                        return this.normal;
                    }
                }

                private Color backEnterColor = Color.Empty;
                private Color textEnterColor = Color.Empty;
                private ItemAppearanceObject enter;
                /// <summary>
                /// 鼠标进入状态
                /// </summary>
                [Description("鼠标进入状态")]
                [PropertyOrder(-192)]
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
                [SkinProperty(true, false)]
                public ItemAppearanceObject Enter
                {
                    get
                    {
                        if (this.enter == null)
                            this.enter = new ItemAppearanceObject(this.owner, this, backEnterColor, textEnterColor);
                        return this.enter;
                    }
                }

                #endregion

                public class ItemAppearanceObject : AppearanceObjectBase
                {
                    internal ItemAppearanceObject(ISkinObject owner, AppearanceObjectBase parent, Color backColor, Color textColor) : base(owner, parent)
                    {
                        this.defaultBackColor = backColor;
                        this.defaultTextColor = textColor;
                    }

                    #region 属性

                    private Color skinBackColor = Color.Empty;
                    private readonly Color defaultBackColor = Color.Empty;
                    private Color backColor = Color.Empty;
                    /// <summary>
                    /// 背景颜色
                    /// </summary>
                    [Description("背景颜色")]
                    [PropertyOrder(-158)]
                    [Editor(typeof(AlphaColorEditor), typeof(UITypeEditor))]
                    [SkinProperty(true, false)]
                    public Color BackColor
                    {
                        get
                        {
                            if (this.owner.GetSkinObjectSkinStateCore())
                            {
                                return this.skinBackColor;
                            }

                            if (this.backColor != Color.Empty)
                            {
                                return this.backColor;
                            }

                            return this.defaultBackColor;
                        }
                        set
                        {
                            if (this.backColor == value)
                                return;

                            this.backColor = value;
                            this.Invalidate();
                        }
                    }
                    private bool ShouldSerializeBackColor()
                    {
                        return this.backColor != Color.Empty;
                    }
                    private void ResetBackColor()
                    {
                        this.backColor = Color.Empty;
                        this.Invalidate();
                    }

                    private Color skinTextColor = Color.Empty;
                    private readonly Color defaultTextColor = Color.Empty;
                    private Color textColor = Color.Empty;
                    /// <summary>
                    /// 文本颜色
                    /// </summary>
                    [Description("文本颜色")]
                    [PropertyOrder(-157)]
                    [Editor(typeof(AlphaColorEditor), typeof(UITypeEditor))]
                    [SkinProperty(true, false)]
                    public Color TextColor
                    {
                        get
                        {
                            if (this.owner.GetSkinObjectSkinStateCore())
                            {
                                return this.skinTextColor;
                            }

                            if (this.textColor != Color.Empty)
                            {
                                return this.textColor;
                            }

                            return this.defaultTextColor;
                        }
                        set
                        {
                            if (this.textColor == value)
                                return;

                            this.textColor = value;
                            this.Invalidate();
                        }
                    }
                    private bool ShouldSerializeTextColor()
                    {
                        return this.textColor != Color.Empty;
                    }
                    private void ResetTextColor()
                    {
                        this.textColor = Color.Empty;
                        this.Invalidate();
                    }

                    #endregion

                }

            }

            public class PaginationAppearanceObject : AppearanceObjectBase
            {
                internal PaginationAppearanceObject(ISkinObject owner, AppearanceObjectBase parent) : base(owner, parent) { }

                #region 属性

                private ItemAppearanceObject normal;
                /// <summary>
                /// 正常状态
                /// </summary>
                [Description("正常状态")]
                [PropertyOrder(-194)]
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
                [SkinProperty(true, false)]
                public ItemAppearanceObject Normal
                {
                    get
                    {
                        if (this.normal == null)
                            this.normal = new ItemAppearanceObject(this.owner, this, Color.Empty, SystemColors.ControlText);
                        return this.normal;
                    }
                }

                private ItemAppearanceObject enter;
                /// <summary>
                /// 鼠标进入状态
                /// </summary>
                [Description("鼠标进入状态")]
                [PropertyOrder(-192)]
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
                [SkinProperty(true, false)]
                public ItemAppearanceObject Enter
                {
                    get
                    {
                        if (this.enter == null)
                            this.enter = new ItemAppearanceObject(this.owner, this, SystemColors.GradientInactiveCaption, SystemColors.ControlText);
                        return this.enter;
                    }
                }

                private ItemAppearanceObject current;
                /// <summary>
                /// 当前状态
                /// </summary>
                [Description("当前状态")]
                [PropertyOrder(-190)]
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
                [SkinProperty(true, false)]
                public ItemAppearanceObject Current
                {
                    get
                    {
                        if (this.current == null)
                            this.current = new ItemAppearanceObject(this.owner, this, SystemColors.ActiveCaption, SystemColors.Window);
                        return this.current;
                    }
                }

                #endregion

                public class ItemAppearanceObject : AppearanceObjectBase
                {
                    internal ItemAppearanceObject(ISkinObject owner, AppearanceObjectBase parent, Color backColor, Color textColor) : base(owner, parent)
                    {
                        this.defaultBackColor = backColor;
                        this.defaultTextColor = textColor;
                    }

                    #region 属性

                    private Color skinBackColor = Color.Empty;
                    private readonly Color defaultBackColor = Color.Empty;
                    private Color backColor = Color.Empty;
                    /// <summary>
                    /// 背景颜色
                    /// </summary>
                    [Description("背景颜色")]
                    [PropertyOrder(-158)]
                    [Editor(typeof(AlphaColorEditor), typeof(UITypeEditor))]
                    [SkinProperty(true, false)]
                    public Color BackColor
                    {
                        get
                        {
                            if (this.owner.GetSkinObjectSkinStateCore())
                            {
                                return this.skinBackColor;
                            }

                            if (this.backColor != Color.Empty)
                            {
                                return this.backColor;
                            }

                            return this.defaultBackColor;
                        }
                        set
                        {
                            if (this.backColor == value)
                                return;

                            this.backColor = value;
                            this.Invalidate();
                        }
                    }
                    private bool ShouldSerializeBackColor()
                    {
                        return this.backColor != Color.Empty;
                    }
                    private void ResetBackColor()
                    {
                        this.backColor = Color.Empty;
                        this.Invalidate();
                    }

                    private Color skinTextColor = Color.Empty;
                    private readonly Color defaultTextColor = Color.Empty;
                    private Color textColor = Color.Empty;
                    /// <summary>
                    /// 文本颜色
                    /// </summary>
                    [Description("文本颜色")]
                    [PropertyOrder(-157)]
                    [Editor(typeof(AlphaColorEditor), typeof(UITypeEditor))]
                    [SkinProperty(true, false)]
                    public Color TextColor
                    {
                        get
                        {
                            if (this.owner.GetSkinObjectSkinStateCore())
                            {
                                return this.skinTextColor;
                            }

                            if (this.textColor != Color.Empty)
                            {
                                return this.textColor;
                            }

                            return this.defaultTextColor;
                        }
                        set
                        {
                            if (this.textColor == value)
                                return;

                            this.textColor = value;
                            this.Invalidate();
                        }
                    }
                    private bool ShouldSerializeTextColor()
                    {
                        return this.textColor != Color.Empty;
                    }
                    private void ResetTextColor()
                    {
                        this.textColor = Color.Empty;
                        this.Invalidate();
                    }

                    #endregion

                }

            }

        }

        #endregion

    }
}
